/**
 *  @file
 *  
 *  This is the ScorePane.  It is in charge of keeping and displaying the 
 *  game score.  It provides an interface for other objects to report to.
 *  The purpose is to keep scoring logic separate from gaming logic, 
 *  which is already vast at this time.
 */
package core;

import javax.swing.JPanel;
import javax.swing.JLabel;

import java.awt.GridLayout;
import java.awt.Color;

public class ScorePane extends JPanel {

  private int score;         // The current score  of this game
  private int linesCleared;  // The # of cleared lines recorded in this game
  private int level;         // The current level of the game
  
  // Display Components
  private JLabel scoreLabel   = new JLabel("Score");
  private JLabel scoreDisplay = new JLabel("0");
  
  // Scoring data for line clearing
  private final int BASE_LINE_CLEAR_1 = 100;
  private final int BASE_LINE_CLEAR_2 = 300;
  private final int BASE_LINE_CLEAR_3 = 700;
  private final int BASE_LINE_CLEAR_4 = 1200;
  
  // Scoring data for dropping a tetro
  private final int BASE_TETRO_DROP = 1;
  
  // Min/Max validation #s
  private final int MIN_LINE_CLEAR = 1;
  private final int MAX_LINE_CLEAR = 4;
  
  /**
   * Create a new score pane
   * 
   * @param level
   *   The starting level of the game
   */
  public ScorePane(int level) {
  
    // Set the game level
    this.level = level;
    
    // Initialize scoring statistics
    this.score = 0;
    this.linesCleared = 0;
    
    // Now we'll setup the panel dimensions and stats
    setLayout(new GridLayout(4, 2));
    setVisible(true);
    setSize(200, 200);
    setBackground(Color.red);
    add(scoreLabel);
    add(scoreDisplay);
  }
  
  /**
   * Notifies the scoreboard that a single line has been cleared
   */
  public void clearLine() {
  
    // Increment line counter and increase score
    linesCleared++;
    increaseScore(adjustedClearScore(BASE_LINE_CLEAR_1));
    
    // Level up if it is time
    if (isLevelUpEarned()) {
    
      levelUp();
    }
  }
  
  /**
   * Notifies the scoreboard that a given number of lines have been cleared
   * 
   * @param lineAmount
   *   The number of lines that were cleared
   */
  public void clearLines(int lineAmount) {
  
    if (lineAmount < MIN_LINE_CLEAR || lineAmount > MAX_LINE_CLEAR) {
    
      // TODO:  Throw exceptions for invalid line amounts
      return;
    }
  
    // Increment Line Counter
    linesCleared += lineAmount;
    
    // Score
    switch(lineAmount) {
    
      case(1): {
    
        increaseScore(adjustedClearScore(BASE_LINE_CLEAR_1));
        break;
      }
     
      case(2): {
      
        increaseScore(adjustedClearScore(BASE_LINE_CLEAR_2));
        break;
      } 
      
      case(3): {
      
        increaseScore(adjustedClearScore(BASE_LINE_CLEAR_3));
        break;
      }
      
      case(4): {
      
        increaseScore(adjustedClearScore(BASE_LINE_CLEAR_4));
        break;
      }
      
      default: {
      
        // Do nothing
      }
    }    
    
    // Level up if it is time
    if (isLevelUpEarned()) {
    
      levelUp();
    }
  } 
  
  /**
   * Notifies the scoreboard that a tetromino has landed
   */
  public void dropTetro() {
  
    increaseScore(adjustedDropScore());
  }
  
  /**
   * Returns the current level
   */
  public int getLevel() {
  
    return level;
  }
  
  /**
   * Figures whether or not enough lines have been cleared to level up
   * 
   * @return
   * 
   *   Returns true if a levelup should occur
   */
  private boolean isLevelUpEarned() {
  
    return false;
  }
  
  /**
   * Increases the level of the game
   */
  private void levelUp() {
  
  } 
  
  /**
   * Returns the adjusted (calculated) line clear score,
   * based on level.
   */
  private int adjustedClearScore(int score) {
  
   return (int) (score * level);
  }
  
  /**
   * Returns the adjusted (calculated) tetro drop score,
   * based on level.
   */
  private int adjustedDropScore() {
  
    return (int) (BASE_TETRO_DROP * level);
  }
  
  /**
   * Increases the score on the board and displays that score
   * 
   * @param int points
   *   This is the amount of points by which to raise thw score.
   */
  private void increaseScore(int points) {
  
    System.out.println(points);
    
    score += points;
    scoreDisplay.setText(Integer.toString(score));
    
    repaint();
  }
}
